<template>
  <el-dialog
    title="多实例配置"
    width="600px"
    v-model="dialogVisible"
    append-to-body
    :close-on-press-escape="false"
    :close-on-click-modal="false"
    @closed="$emit('close')"
  >
    <el-descriptions :column="1" border>
      <el-descriptions-item label="使用说明">
        按照BPMN2.0规范的要求，用于为每个实例创建执行的父执行，会提供下列变量:
      </el-descriptions-item>
      <el-descriptions-item label="nrOfInstances">实例总数。</el-descriptions-item>
      <el-descriptions-item label="nrOfActiveInstances">
        当前活动的（即未完成的），实例数量。对于顺序多实例，这个值总为1。
      </el-descriptions-item>
      <el-descriptions-item label="nrOfCompletedInstances">
        已完成的实例数量。
      </el-descriptions-item>
      <el-descriptions-item label="loopCounter">
        给定实例在for-each循环中的index。
      </el-descriptions-item>
    </el-descriptions>
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
      <el-form-item prop="collection">
        <template #label>
          <div class="flex flex-row items-center">
            <div>集合</div>
            <el-tooltip placement="top">
              <template #content>
                collection: 属性会作为表达式进行解析。如果表达式解析为字符串而不是一个集合，<br />不论是因为本身配置的就是静态字符串值，还是表达式计算结果为字符串，<br />这个字符串都会被当做变量名，并从流程变量中用于获取实际的集合。
              </template>
              <el-icon>
                <question-filled />
              </el-icon>
            </el-tooltip>
          </div>
        </template>
        <el-input v-model="formData.collection" />
      </el-form-item>
      <el-form-item prop="elementVariable">
        <template #label>
          <div class="flex flex-row items-center">
            <div>元素变量</div>
            <el-tooltip placement="top">
              <template #content>
                elementVariable:
                每创建一个用户任务前，先以该元素变量为label，集合中的一项为value，<br />创建（局部）流程变量，该局部流程变量被用于指派用户任务。<br />一般来说，该字符串应与指定人员变量相同。
              </template>
              <el-icon>
                <question-filled />
              </el-icon>
            </el-tooltip>
          </div>
        </template>
        <el-input v-model="formData.elementVariable" />
      </el-form-item>
      <el-form-item prop="isSequential">
        <template #label>
          <div class="flex flex-row items-center">
            <div>执行方式</div>
            <el-tooltip placement="top">
              <template #content>
                并行会签（parallel）、串行会签(sequential)，其中并行会签的意思是
                多个人同时执行任务。串行会签是按顺序执行任务。
              </template>
              <el-icon>
                <question-filled />
              </el-icon>
            </el-tooltip>
          </div>
        </template>
        <el-select v-model="formData.isSequential">
          <el-option label="串行" :value="true" />
          <el-option label="并行" :value="false" />
        </el-select>
      </el-form-item>
      <el-form-item prop="completionCondition">
        <template #label>
          <div class="flex flex-row items-center">
            <div>完成条件</div>
            <el-tooltip placement="top">
              <template #content>
                completionCondition:
                多实例活动在所有实例都完成时结束，然而也可以指定一个表达式，在每个实例<br />结束时进行计算。当表达式计算为true时，将销毁所有剩余的实例，并结束多实例<br />活动，继续执行流程。例如
                ${nrOfCompletedInstances/nrOfInstances >= 0.6 }，<br />表示当任务完成60%时，该节点就算完成
              </template>
              <el-icon>
                <question-filled />
              </el-icon>
            </el-tooltip>
          </div>
        </template>
        <el-input v-model="formData.completionCondition" />
      </el-form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="save">确定</el-button>
        <el-button @click="formData = {}">清空</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup>
  import { ref, onMounted, defineProps } from 'vue';
  import mixinPanel from '../../../common/mixinPanel';
  import { formatJsonKeyValue } from '../../../common/parseElement';

  const props = defineProps({
    modeler: {
      type: Object,
      required: true,
    },
    element: {
      type: Object,
      required: true,
    },
    categorys: {
      type: Array,
      default: () => [],
    },
  });

  const formRef = ref(null);
  const formData = ref({});
  const formRules = ref({});
  const dialogVisible = ref(true);
  const prefix = ref('flowable:');

  const { updateProperties } = mixinPanel(props.modeler, props.element, formData);

  onMounted(() => {
    const cache = JSON.parse(
      JSON.stringify(props.element.businessObject.loopCharacteristics ?? {}),
    );
    cache.completionCondition = cache.completionCondition?.body;
    // 拼接多实例对象
    if (props.element.businessObject.loopCharacteristics) {
      Object.assign(cache, props.element.businessObject.loopCharacteristics.$attrs);
    }
    formData.value = formatJsonKeyValue(cache);
  });

  function updateElement() {
    if (formData.value.isSequential !== null && formData.value.isSequential !== undefined) {
      // const model = props.modeler.get('moddle');
      let loopCharacteristics = props.element.businessObject.get('loopCharacteristics');
      if (!loopCharacteristics) {
        loopCharacteristics = props.modeler
          .get('moddle')
          .create('bpmn:MultiInstanceLoopCharacteristics');
      }
      loopCharacteristics['isSequential'] = formData.value.isSequential;
      loopCharacteristics['collection'] = formData.value.collection;
      loopCharacteristics['elementVariable'] = formData.value.elementVariable;
      // let loopCardinality = model.create("bpmn:Expression",{
      //   body: "4"
      // });
      // loopCharacteristics['loopCardinality'] = loopCardinality

      loopCharacteristics.$attrs['isSequential'] = formData.value.isSequential;
      loopCharacteristics.$attrs[prefix.value + 'collection'] = formData.value.collection;
      loopCharacteristics.$attrs[prefix.value + 'elementVariable'] = formData.value.elementVariable;

      if (formData.value.completionCondition) {
        loopCharacteristics['completionCondition'] = props.modeler
          .get('moddle')
          .create('bpmn:Expression', { body: formData.value.completionCondition });
      }
      updateProperties({ loopCharacteristics: loopCharacteristics });
    } else {
      delete props.element.businessObject.loopCharacteristics;
    }
  }

  function save() {
    formRef.value.validate((valid) => {
      if (valid) {
        updateElement();
        dialogVisible.value = false;
      }
    });
  }
</script>

<style scoped lang="scss"></style>
